using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using AppExtensions.Presenters;
using AppExtensions.Views;
using System.Web.Security;
using AspNetExtensions.Web.SessionState;
using System.Web;
using System.Threading;
using System.Globalization;

namespace AspNetExtensions.Pages
{
    public abstract class BasePage<TPresenter, TView> : Page, IBaseView where TPresenter : BasePresenter<TView>, new() where TView : IBaseView
    {
        private SessionDictionaryWrapper sessionWrapper;
        protected TPresenter presenter;

        public BasePage()
        {
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            this.presenter = new TPresenter();
            this.presenter.Params = this.Request.Params;
            this.presenter.View = (TView)(object)this;
            this.sessionWrapper = new SessionDictionaryWrapper(this.Session);
            this.presenter.OnViewInitialized();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            this.presenter.OnViewLoaded();
            if (!Page.IsPostBack)
            {
                this.presenter.OnViewFirstLoaded();
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.presenter.OnPreRender();
        }

        protected override void InitializeCulture()
        {
          // TODO Clean up magic strings
          string lang = string.Empty;
          //default to the invariant culture

          if (this.sessionWrapper["Lang"] != null)
          {
            lang = (string)sessionWrapper["Lang"];
            if (!object.ReferenceEquals(lang, "auto"))
            {
              Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);
            }
            else
            {
              Thread.CurrentThread.CurrentUICulture = CultureInfo.CurrentCulture;
            }
            //Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang)
          }

          base.InitializeCulture();
        }

        #region IBaseView Members

        void IBaseView.RedirectTo(string url)
        {
            Response.Redirect(Server.UrlPathEncode(this.ResolveUrl(url)));
        }

        void IBaseView.RedirectToLogin()
        {
            // Redirects to the login, but then comes back to this page
            FormsAuthentication.RedirectToLoginPage(Request.RawUrl);
            Response.End();
        }

        void IBaseView.RedirectTo(string url, params KeyValuePair<string, string>[] parameterValues)
        {
            if (parameterValues.Length > 0)
            {
                StringBuilder sb = new StringBuilder(url);
                bool isFirst = true;
                foreach (KeyValuePair<string, string> pair in parameterValues)
                {
                    if (isFirst)
                        sb.Append("?");
                    else
                        sb.Append("&");
                    sb.AppendFormat("{0}={1}", Server.UrlEncode(pair.Key), Server.UrlEncode(pair.Value));
                    isFirst = false;
                }
                url = sb.ToString();
            }
            ((IBaseView)this).RedirectTo(url);
        }

        public void RenderToHandler(IHttpHandler handler)
        {
            Server.Transfer(handler, true);
        }

        IDictionary<string, object> IBaseView.Session
        {
            get
            {
                return this.sessionWrapper;
            }
        }

        string IBaseView.ClientIPAddress
        {
            get { return Context.Request.UserHostAddress; }
        }

        long? IBaseView.UserId
        {
            get
            {
                MembershipUser user = Membership.GetUser(true);
                if (user != null)
                    return (long)user.ProviderUserKey;
                else
                    return null;
            }
        }
        #endregion

    }
}
